#include "punto.h"

void imprimePunto(Punto p){
	printf("(%i,%i)\n",p.x,p.y);
}
void imprimePuntos(ListaPunto puntos){
	int i;
	NodoPunto* nodo = puntos->primero;
	while(nodo){
		printf("(%i,%i)\t%i\n",nodo->punto.x,nodo->punto.y,&nodo->punto);
		nodo = nodo->siguiente;
	}
}

void imprimePerimetro(puntoDelEspacio** espacio, int maxX, int maxY){
	int i,j;

	for(i = 0; i < maxX ; i++){
		for(j = 0; j < maxY ; j++){
			if(espacio[i][j] == PERIMETRO)
				printf("(%i,%i)\n",i,j);
		}
	}
}

void inicializaPuntos(ListaPunto puntos, int numPuntos, int maxX, int maxY){
	if(!puntos || puntos->tamanyo != 0){
		printf("\nERROR: La lista de puntos no está vacia o no está inicializada\n");
		exit(2);
	}
	
	Punto punto;
	int i;
	for(i = 0 ; i < numPuntos ; i++){
		punto.x = rand()%(maxX+1);
		punto.y = rand()%(maxY+1);
		
		ls_add(puntos, punto);
	}
}

void inicializaEspacio(puntoDelEspacio** espacio, int maxX, int maxY){
	int i,j;

	for(i = 0; i < maxX ; i++)
		for(j = 0; j < maxY ; j++)
			espacio[i][j] = ESPACIO_LIBRE;
}

void ponPunto(int x, int y, ListaPunto puntosMoviles, puntoDelEspacio** espacio, int* minRX, int* maxRX, int* minRY, int* maxRY, int maxX, int maxY){
	Punto p = {x,y};
	
	if(espacio[x][y] == ESPACIO_LIBRE)
		ls_add(puntosMoviles,p);
	else{
		espacio[x][y] = PUNTO_QUIETO;
		ponPerimetro(p, espacio, minRX, maxRX, minRY, maxRY, maxX, maxY);
	}
}

void ponPuntoQuieto(Punto punto, puntoDelEspacio** espacio, int* minRX, int* maxRX, int* minRY, int* maxRY, int maxX, int maxY){
	
	espacio[punto.x][punto.y] = PUNTO_QUIETO;
	
	ponPerimetro(punto, espacio, minRX, maxRX, minRY, maxRY, maxX, maxY);
}

void ponPerimetro(Punto punto, puntoDelEspacio** espacio, int* minRX, int* maxRX, int* minRY, int* maxRY, int maxX, int maxY){
	int i,j;	//Índices para acceder al espacio
	int k,l;	//Índices para controlar las repeticiones
	
	for(k = 0, i = punto.x-1 ; k < 3 ; k++, i++){
		for (l = 0, j = punto.y-1 ; l < 3 ; l++, j++){
			if(i < 0)		i = maxX-1;
			else if(i >= maxX)	i = 0;
			if(j < 0)		j = maxY -1;
			else if(j >= maxY)	j = 0;
			
			//Si no estamos encima de ningún punto quieto ponemos el espacio
			if(espacio[i][j] == ESPACIO_LIBRE){
				espacio[i][j] = PERIMETRO;
				
				//Actualizamos los mínimos y máximos relativos
				if(i < *minRX)	*minRX = i;
				else if(i >= *maxRX)	*maxRX = i+1;
				
				if(j < *minRY)	*minRY = j;
				else if(j >= *maxRY)	*maxRY = j+1;
			}
		}
	}
	
	
}

void muevePuntos(ListaPunto puntosMoviles, puntoDelEspacio** espacio, int* minRX, int* maxRX, int* minRY, int* maxRY, int maxX, int maxY){
	int i; //índice para el f

	NodoPunto* nodo = puntosMoviles->primero;
	NodoPunto* nodoAnt = nodo;
	for(; nodo ; nodoAnt = nodo, nodo = nodo->siguiente){
		
		printf("(%i,%i)--->",nodo->punto.x,nodo->punto.y);
		
		//Movemos aleatoriamente +- una unidad
		nodo->punto.x += rand()%3 - 1;
		nodo->punto.y += rand()%3 - 1;
		
		//Si se sale de los limites del espacio aperece en el lado contrario
		if(nodo->punto.x < 0) nodo->punto.x= maxX-1;
		else if(nodo->punto.x > maxX-1) nodo->punto.x = 0;
		if(nodo->punto.y < 0) nodo->punto.y = maxY-1;
		else if(nodo->punto.y > maxY-1) nodo->punto.y = 0;
		
		printf("(%i,%i)\t%i\n",nodo->punto.x,nodo->punto.y,&nodo->punto);
		
		//Comprobamos si hay colisión y actualizamos las listas de puntos y el espacio
		//NOTA: Un punto colisionará con un punto quieto sólo en el caso de que ambos 
		//hayan incidido a la vez en el espacio, de ahí que también se compruebe
		if(espacio[nodo->punto.x][nodo->punto.y] != ESPACIO_LIBRE){
			   
				espacio[nodo->punto.x][nodo->punto.y] = PUNTO_QUIETO;
				ponPerimetro(nodo->punto, espacio, minRX, maxRX, minRY, maxRY, maxX, maxY);
				
				//Eliminamos el punto de la lista 'puntos'
				if(puntosMoviles->primero == nodo){
					puntosMoviles->primero = nodo->siguiente;
					
					//Si es el último y el primero
					if(puntosMoviles->ultimo == nodo)
						puntosMoviles->ultimo = NULL;
				}	
				else{
					nodoAnt->siguiente = nodo->siguiente;
				}
					
				puntosMoviles->tamanyo--;
				printf("free: (%i,%i)\t%i",nodo->punto.x,nodo->punto.y,&nodo->punto);
				free(nodo);
				printf("\t liberado\n");
		}
	}
}
